home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 26.3 KB | 940 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: SLRegion.cpp
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "FWErrors.h"
-
- #include "FWOS.hpp"
-
- #ifndef SLREGION_H
- #include "SLRegion.h"
- #endif
-
- #ifndef FWFXMATH_H
- #include "FWFxMath.h"
- #endif
-
- #ifndef FWRECT_H
- #include "FWRect.h"
- #endif
-
- #ifndef FWPOINT_H
- #include "FWPoint.h"
- #endif
-
- #ifndef SLGRGLOB_H
- #include "SLGrGlob.h"
- #endif
-
- #ifndef PRGRUTIL_H
- #include "PRGrUtil.h"
- #endif
-
- #ifndef FWPRIDEB_H
- #include "FWPriDeb.h"
- #endif
-
- #ifndef FWSTRMRW_H
- #include "FWStrmRW.h"
- #endif
-
- #ifndef FWMEMHLP_H
- #include "FWMemHlp.h"
- #endif
-
- #ifndef FWMEMMGR_H
- #include "FWMemMgr.h"
- #endif
-
- #ifdef FW_BUILD_MAC
- #pragma segment FWGraphx_Region
- #endif
-
- //========================================================================================
- // Local helpers
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- static GrafPtr PrivMacOpenRegion();
- static ODRgnHandle PrivMacCloseRegion(GrafPtr svPort);
- #endif
-
- #ifdef FW_BUILD_WIN
- static void PrivWinInsetRegionRectangle(LPPOINT lppt, int dx, int dy, const POINT& ptCenter);
- static void PrivWinInsetRegionRectangle(LPRECT lpRect, int dx, int dy, const POINT& ptCenter);
- #endif
-
- //========================================================================================
- // Region functions
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_CreateRectRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle SL_API FW_CreateRectRegion(const FW_SRect& rect)
- {
- // No try block necessary - Do not throw
- FW_CPlatformRect plfmRect = rect;
-
- #ifdef FW_BUILD_MAC
- ODRgnHandle rgn = ::FW_NewRegion();
- ::RectRgn(rgn, &plfmRect);
- return rgn;
- #endif
- #ifdef FW_BUILD_WIN
- return ::CreateRectRgnIndirect(&plfmRect);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CreateOvalRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle SL_API FW_CreateOvalRegion(const FW_SRect& rect)
- {
- // No try block necessary - Do not throw
- FW_CPlatformRect plfmRect(rect);
-
- #ifdef FW_BUILD_MAC
- GrafPtr svPort = PrivMacOpenRegion();
- ::FrameOval(&plfmRect);
- return PrivMacCloseRegion(svPort);
- #endif
-
- #ifdef FW_BUILD_WIN
- return ::CreateEllipticRgnIndirect(&plfmRect);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CreateRoundRectRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle SL_API FW_CreateRoundRectRegion(const FW_SRect& rect, const FW_SPoint& ovalSize)
- {
- // No try block necessary - Do not throw
- FW_CPlatformRect plfmRect(rect);
- FW_CPlatformPoint plfmPoint(ovalSize);
-
- #ifdef FW_BUILD_MAC
- GrafPtr svPort = PrivMacOpenRegion();
- ::FrameRoundRect(&plfmRect, plfmPoint.X(), plfmPoint.Y());
- return ::PrivMacCloseRegion(svPort);
- #endif
- #ifdef FW_BUILD_WIN
- return ::CreateRoundRectRgn(plfmRect.left, plfmRect.top,
- plfmRect.right, plfmRect.bottom,
- plfmPoint.X(), plfmPoint.Y());
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CreateArcRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle SL_API FW_CreateArcRegion(const FW_SRect& rect,
- short startAngle, short arcAngle)
- {
- // No try block necessary - Do not throw
- // However, if a memory error occurs, we may return NULL!
-
- FW_CPlatformRect plfmRect(rect);
-
- // first, we make a polygon with the segmented arc a little outside of the tru arc
-
- const unsigned short enlargeFactor = 8; // magic number: we enlarge the rectangle
- const short width = plfmRect.right - plfmRect.left;
- const short height = plfmRect.bottom - plfmRect.top;
- short outset = FW_FixedToInt(FW_Sqrt(FW_IntToFixed(width / enlargeFactor)));
-
- plfmRect.left -= outset;
- plfmRect.right += outset;
-
- if(width != height)
- outset = FW_FixedToInt(FW_Sqrt(FW_IntToFixed(height / enlargeFactor)));
-
- plfmRect.top -= outset;
- plfmRect.bottom += outset;
-
- // normalize the starting point and arc angles for the coord system used by Quickdraw
-
- if (startAngle >= 360)
- startAngle = startAngle % 360;
- else if (startAngle < 0)
- startAngle = (startAngle % 360) + 360;
-
- if (arcAngle > 360)
- arcAngle = arcAngle % 360;
- else if (arcAngle < 0)
- arcAngle = (arcAngle % 360) + 360;
-
- // start with a new, empty region
- ODRgnHandle hArcRegion = FW_NewRegion();
-
- if(arcAngle != 0)
- {
- const ODUShort kAnglePerSegment = 5; // one line segment for every kAnglePerSegment degrees
- const ODUShort kMaxPoints = (360 / kAnglePerSegment) + 1; // max segments + 1
-
- ODUShort numSegments = arcAngle / kAnglePerSegment;
-
- ODUShort angle = startAngle;
-
- FW_SPoint pt[kMaxPoints + 1]; // (numSegments + 1) points for the arc plus one for the center
- for (ODUShort i = 0; i <= numSegments; i++) // we create numSegments +1 points for the arc
- {
- angle = startAngle + arcAngle * i / numSegments;
-
- FW_CPlatformPoint tempPt;
- FW_PrivCalcArcPoints(plfmRect, angle, tempPt);
- pt[i].x = FW_IntToFixed(tempPt.h);
- pt[i].y = FW_IntToFixed(tempPt.v);
- }
-
- // add the vertex to the array
- pt[numSegments + 1].x = FW_Half(rect.left + rect.right);
- pt[numSegments + 1].y = FW_Half(rect.top + rect.bottom);
-
- ODRgnHandle hPolygonRgn = ::FW_CreatePolygonRegion(numSegments + 2, pt);
-
- if(hPolygonRgn != NULL)
- {
- ODRgnHandle hEllipticRgn = FW_CreateOvalRegion(rect);
-
- #ifdef FW_BUILD_MAC
- ::SectRgn(hEllipticRgn, hPolygonRgn, hArcRegion);
-
- if(::QDError() != noErr)
- {
- FW_DisposeRegion(hArcRegion);
- hArcRegion = NULL;
- }
-
- #endif
- #ifdef FW_BUILD_WIN
- ::CombineRgn(hArcRegion, hEllipticRgn, hPolygonRgn, RGN_AND);
- #endif
-
- FW_DisposeRegion(hEllipticRgn);
- }
-
- FW_DisposeRegion(hPolygonRgn);
- }
-
- // Return the result
- return hArcRegion;
- }
-
-
- #ifdef FW_BUILD_MAC
-
- //----------------------------------------------------------------------------------------
- // FW_PrivMacDrawPolyPoints
- //----------------------------------------------------------------------------------------
-
- inline void FW_PrivMacDrawPolyPoints(unsigned long pointCount, const FW_SPoint* pointArray, Boolean closed)
- {
- FW_CPlatformPoint startPt = pointArray[0];
- FW_CPlatformPoint lastPt = startPt;
- FW_CPlatformPoint pt;
-
- ::MoveTo(startPt.h, startPt.v);
-
- for(unsigned long i = 1; i < pointCount; i ++)
- {
- pt = pointArray[i];
- if(pt != lastPt)
- {
- lastPt = pt;
- ::LineTo(pt.h, pt.v);
- }
- }
-
- if(closed && (startPt != pt))
- ::LineTo(startPt.h, startPt.v);
- }
-
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CreatePolygonRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle SL_API FW_CreatePolygonRegion(unsigned long pointCount, const FW_SPoint* pointArray)
- {
- // No try block necessary - Do not throw
- #ifdef FW_BUILD_MAC
- GrafPtr savePort = ::PrivMacOpenRegion();
-
- FW_PrivMacDrawPolyPoints(pointCount, pointArray, true);
-
- ODRgnHandle resultRgn = ::PrivMacCloseRegion(savePort);
-
- return resultRgn;
- #endif
- #ifdef FW_BUILD_WIN
- FW_CPlatformPoint* points = new FW_CPlatformPoint[pointCount];
-
- for(unsigned long i = 0; i < pointCount; i ++)
- points[i] = pointArray[i];
-
- HRGN hRgn = ::CreatePolygonRgn(points, pointCount, ALTERNATE);
- delete[] points;
-
- return hRgn;
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CreateLineRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle SL_API FW_CreateLineRegion(const FW_SPoint& startPt,
- const FW_SPoint& endPt,
- const FW_SPoint& lineThickness)
- {
- // No try block necessary - Do not throw
- ODRgnHandle rgn;
-
- FW_CPlatformPoint firstPoint(startPt);
- FW_CPlatformPoint lastPoint(endPt);
- FW_CPlatformPoint penSize(lineThickness);
-
- FW_CPlatformRect halfPen(-penSize.X() / 2, -penSize.Y() / 2, (penSize.X() + 1) / 2, (penSize.Y() + 1) / 2);
-
- FW_CPlatformRect rect(firstPoint.X() + halfPen.left, firstPoint.Y() + halfPen.top, firstPoint.X() + halfPen.right, firstPoint.Y() + halfPen.bottom);
-
- short regionCode = 0;
- if (lastPoint.X() < rect.left)
- regionCode = 0x0008;
- else if (lastPoint.X() > rect.right)
- regionCode = 0x0004;
-
- if (lastPoint.Y() < rect.top)
- regionCode |= 0x0001;
- else if (lastPoint.Y() > rect.bottom)
- regionCode |= 0x0002;
-
- short nbPoint;
- FW_CPlatformPoint pt[6];
-
- switch (regionCode)
- {
- case 0x0000:
- pt[0].Set(firstPoint.X() + halfPen.left, firstPoint.Y() + halfPen.top);
- pt[1].Set(lastPoint.X() + halfPen.right, lastPoint.Y() + halfPen.bottom);
- nbPoint = 2;
- break;
- case 0x0004:
- pt[0].Set(firstPoint.X() + halfPen.left, firstPoint.Y() + halfPen.top);
- pt[1].Set(lastPoint.X() + halfPen.right, lastPoint.Y() + halfPen.bottom);
- nbPoint = 2;
- break;
- case 0x0008:
- pt[0].Set(lastPoint.X() + halfPen.left, firstPoint.Y() + halfPen.top);
- pt[1].Set(firstPoint.X() + halfPen.right, lastPoint.Y() + halfPen.bottom);
- nbPoint = 2;
- break;
- case 0x0002:
- pt[0].Set(firstPoint.X() + halfPen.left, firstPoint.Y() + halfPen.top);
- pt[1].Set(lastPoint.X() + halfPen.right, lastPoint.Y() + halfPen.bottom);
- nbPoint = 2;
- break;
- case 0x0001:
- pt[0].Set(firstPoint.X() + halfPen.left, lastPoint.Y() + halfPen.top);
- pt[1].Set(lastPoint.X() + halfPen.right, firstPoint.Y() + halfPen.bottom);
- nbPoint = 2;
- break;
- case 0x0005:
- pt[0].Set(firstPoint.X() + halfPen.left, firstPoint.Y() + halfPen.top);
- pt[1].Set(firstPoint.X() + halfPen.left, firstPoint.Y() + halfPen.bottom);
- pt[2].Set(firstPoint.X() + halfPen.right, firstPoint.Y() + halfPen.bottom);
- pt[3].Set(lastPoint.X() + halfPen.right, lastPoint.Y() + halfPen.bottom);
- pt[4].Set(lastPoint.X() + halfPen.right, lastPoint.Y() + halfPen.top);
- pt[5].Set(lastPoint.X() + halfPen.left, lastPoint.Y() + halfPen.top);
- nbPoint = 6;
- break;
- case 0x0006:
- pt[0].Set(firstPoint.X() + halfPen.right, firstPoint.Y() + halfPen.top);
- pt[1].Set(firstPoint.X() + halfPen.left, firstPoint.Y() + halfPen.top);
- pt[2].Set(firstPoint.X() + halfPen.left, firstPoint.Y() + halfPen.bottom);
- pt[3].Set(lastPoint.X() + halfPen.left, lastPoint.Y() + halfPen.bottom);
- pt[4].Set(lastPoint.X() + halfPen.right, lastPoint.Y() + halfPen.bottom);
- pt[5].Set(lastPoint.X() + halfPen.right, lastPoint.Y() + halfPen.top);
- nbPoint = 6;
- break;
- case 0x000A:
- pt[0].Set(firstPoint.X() + halfPen.left, firstPoint.Y() + halfPen.top);
- pt[1].Set(firstPoint.X() + halfPen.right, firstPoint.Y() + halfPen.top);
- pt[2].Set(firstPoint.X() + halfPen.right, firstPoint.Y() + halfPen.bottom);
- pt[3].Set(lastPoint.X() + halfPen.right, lastPoint.Y() + halfPen.bottom);
- pt[4].Set(lastPoint.X() + halfPen.left, lastPoint.Y() + halfPen.bottom);
- pt[5].Set(lastPoint.X() + halfPen.left, lastPoint.Y() + halfPen.top);
- nbPoint = 6;
- break;
- case 0x0009:
- pt[0].Set(firstPoint.X() + halfPen.right, firstPoint.Y() + halfPen.top);
- pt[1].Set(firstPoint.X() + halfPen.right, firstPoint.Y() + halfPen.bottom);
- pt[2].Set(firstPoint.X() + halfPen.left, firstPoint.Y() + halfPen.bottom);
- pt[3].Set(lastPoint.X() + halfPen.left, lastPoint.Y() + halfPen.bottom);
- pt[4].Set(lastPoint.X() + halfPen.left, lastPoint.Y() + halfPen.top);
- pt[5].Set(lastPoint.X() + halfPen.right, lastPoint.Y() + halfPen.top);
- nbPoint = 6;
- break;
- }
-
- #ifdef FW_BUILD_WIN
- if (nbPoint == 2)
- rgn = ::CreateRectRgn(pt[0].x, pt[0].y, pt[1].x, pt[1].y);
- else
- rgn = ::CreatePolygonRgn(pt, nbPoint, WINDING);
- #endif
-
- #ifdef FW_BUILD_MAC
- if (nbPoint == 2)
- {
- rgn = ::FW_NewRegion();
- FW_CPlatformRect rect(pt[0], pt[1]);
- ::RectRgn(rgn, &rect);
- }
- else
- {
- GrafPtr svPort = ::PrivMacOpenRegion();
- ::MoveTo(pt[0].h, pt[0].v);
- ::LineTo(pt[1].h, pt[1].v);
- ::LineTo(pt[2].h, pt[2].v);
- ::LineTo(pt[3].h, pt[3].v);
- ::LineTo(pt[4].h, pt[4].v);
- ::LineTo(pt[5].h, pt[5].v);
- ::LineTo(pt[0].h, pt[0].v);
- rgn = ::PrivMacCloseRegion(svPort);
- }
- #endif
-
- return rgn;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CopyRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle SL_API FW_CopyRegion(ODRgnHandle scrRgn)
- {
- // No try block necessary - Do not throw
- FW_ASSERT(scrRgn != NULL);
-
- ODRgnHandle newRgn = ::FW_NewRegion();
-
- #ifdef FW_BUILD_MAC
- ::CopyRgn(scrRgn, newRgn);
- #endif
- #ifdef FW_BUILD_WIN
- ::CombineRgn(newRgn, scrRgn, NULL, RGN_COPY);
- #endif
-
- return newRgn;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CopyRegionTo
- //----------------------------------------------------------------------------------------
-
- void SL_API FW_CopyRegionTo(ODRgnHandle scrRgn, ODRgnHandle dstRgn)
- {
- // No try block necessary - Do not throw
- FW_ASSERT(scrRgn != NULL);
- FW_ASSERT(dstRgn != NULL);
-
- #ifdef FW_BUILD_MAC
- ::CopyRgn(scrRgn, dstRgn);
- #endif
- #ifdef FW_BUILD_WIN
- ::CombineRgn(dstRgn, scrRgn, NULL, RGN_COPY);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_NewRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle SL_API FW_NewRegion()
- {
- // No try block necessary - Do not throw
- #ifdef FW_BUILD_MAC
- ODRgnHandle r;
- FW_TRY
- {
- r = (ODRgnHandle)FW_CMemoryManager::AllocateSystemHandle(sizeof(Region));
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING()
- {
- return NULL;
- }
- FW_CATCH_END
- (**r).rgnSize = sizeof(Region);
- SetRect(&(**r).rgnBBox, 0,0,0,0);
- return r;
- #endif
-
- #ifdef FW_BUILD_WIN
- return ::CreateRectRgn(0,0,0,0);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_DisposeRegion
- //----------------------------------------------------------------------------------------
-
- void SL_API FW_DisposeRegion(ODRgnHandle rgn)
- {
- // No try block necessary - Do not throw
- FW_ASSERT(rgn != 0);
-
- #ifdef FW_BUILD_MAC
- FW_CMemoryManager::FreeSystemHandle((FW_PlatformHandle)rgn);
- #endif
- #ifdef FW_BUILD_WIN
- ::DeleteObject(rgn);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_OutlineRegion
- //----------------------------------------------------------------------------------------
-
- void SL_API FW_OutlineRegion(ODRgnHandle rgn, FW_Fixed outlineSize)
- {
- ODRgnHandle tempRgn = ::FW_CopyRegion(rgn);
-
- if (outlineSize <= FW_kFixed0)
- outlineSize = FW_kFixedPos1;
-
- ::FW_InsetRegion(tempRgn, outlineSize, outlineSize);
-
- #ifdef FW_BUILD_MAC
- ::DiffRgn(rgn, tempRgn, rgn);
- #endif
- #ifdef FW_BUILD_WIN
- ::CombineRgn(rgn, rgn, tempRgn, RGN_DIFF);
- #endif
-
- ::FW_DisposeRegion(tempRgn);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_InsetRegion
- //----------------------------------------------------------------------------------------
-
- void SL_API FW_InsetRegion(ODRgnHandle rgn, FW_Fixed x, FW_Fixed y)
- {
- // No try block necessary - Do not throw
- #ifdef FW_BUILD_MAC
- ::InsetRgn(rgn, FW_FixedToInt(x), FW_FixedToInt(y));
- #endif
- #ifdef FW_BUILD_WIN
- int dx = FW_FixedToInt(x);
- int dy = FW_FixedToInt(y);
-
- if (dx == 0 && dy == 0)
- return;
-
- // Note: This code relies on partially documented Windows GDI data structures!
-
- // Get the current region data
- long size = ::GetRegionData(rgn, 0, NULL);
-
- FW_CAcquireTemporaryMemory tempMem(size);
- LPRGNDATA rgnData = (LPRGNDATA) tempMem.GetPointer();
- ::GetRegionData(rgn, size, rgnData);
-
- // Massage the region data
- if(rgnData->rdh.iType == RDH_RECTANGLES)
- {
- POINT ptCenter;
- ptCenter.x = (rgnData->rdh.rcBound.left + rgnData->rdh.rcBound.right) / 2;
- ptCenter.y = (rgnData->rdh.rcBound.top + rgnData->rdh.rcBound.bottom) / 2;
-
- LPRECT lpRect = (LPRECT) rgnData->Buffer;
-
- for(unsigned long i = 0; i < rgnData->rdh.nCount; ++ i, ++ lpRect)
- ::PrivWinInsetRegionRectangle(lpRect, dx, dy, ptCenter);
- }
-
- // Create a new region and replace the one passed in
- HRGN hNewRgn = ::ExtCreateRegion(NULL, size, rgnData);
- if(hNewRgn == NULL)
- FW_Failure(FW_xMemoryExhausted);
-
- ::FW_CopyRegionTo(hNewRgn, rgn);
- ::FW_DisposeRegion(hNewRgn);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_MapRegion
- //----------------------------------------------------------------------------------------
-
- void SL_API FW_MapRegion(ODRgnHandle rgn, const FW_SRect& srcRect, const FW_SRect& dstRect)
- {
- // No try block necessary - Do not throw
- FW_CPlatformRect plfmSrc(srcRect);
- FW_CPlatformRect plfmDst(dstRect);
-
- #ifdef FW_BUILD_MAC
- ::MapRgn(rgn, &plfmSrc, &plfmDst);
- #endif
- #ifdef FW_BUILD_WIN
- // Get the current region data
- long size = ::GetRegionData(rgn, 0, NULL);
-
- FW_CAcquireTemporaryMemory tempMem(size);
- LPRGNDATA rgnData = (LPRGNDATA) tempMem.GetPointer();
- ::GetRegionData(rgn, size, rgnData);
-
- // Figure out the desired transform
- XFORM xform;
- xform.eM11 = (float) FW_FixedToDouble((dstRect.right - dstRect.left) / (srcRect.right - srcRect.left));
- xform.eM12 = 0.0f;
- xform.eM21 = 0.0f;
- xform.eM22 = (float) FW_FixedToDouble((dstRect.bottom - dstRect.top) / (srcRect.bottom - srcRect.top));
- xform.eDx = (float) FW_FixedToDouble(dstRect.left - srcRect.left);
- xform.eDy = (float) FW_FixedToDouble(dstRect.top - srcRect.top);
-
- // Create a new region and replace the one passed in
- HRGN hNewRgn = ::ExtCreateRegion(&xform, size, rgnData);
- if(hNewRgn == NULL)
- FW_Failure(FW_xMemoryExhausted);
-
- ::FW_CopyRegionTo(hNewRgn, rgn);
- ::FW_DisposeRegion(hNewRgn);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_EmptyRegion
- //----------------------------------------------------------------------------------------
-
- void SL_API FW_EmptyRegion(ODRgnHandle rgn)
- {
- // No try block necessary - Do not throw
- #ifdef FW_BUILD_MAC
- ::SetEmptyRgn(rgn);
- #endif
- #ifdef FW_BUILD_WIN
- ::SetRectRgn(rgn, 0, 0, 0, 0);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_OffsetRegion
- //----------------------------------------------------------------------------------------
-
- void SL_API FW_OffsetRegion(ODRgnHandle rgn, FW_Fixed x, FW_Fixed y)
- {
- ::OffsetRgn(rgn, FW_FixedToInt(x), FW_FixedToInt(y));
- }
-
- //----------------------------------------------------------------------------------------
- // FW_GetRegionBoundingBox
- //----------------------------------------------------------------------------------------
-
- void SL_API FW_GetRegionBoundingBox(ODRgnHandle rgn, FW_SRect& rect)
- {
- // No try block necessary - Do not throw
- #ifdef FW_BUILD_MAC
- rect = FW_CRect((*rgn)->rgnBBox);
- #endif
- #ifdef FW_BUILD_WIN
- FW_CPlatformRect plfmRect;
- ::GetRgnBox(rgn, &plfmRect);
- rect = FW_CRect(plfmRect);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_PointInRegion
- //----------------------------------------------------------------------------------------
-
- FW_Boolean SL_API FW_PointInRegion(ODRgnHandle rgn, const FW_SPoint& point)
- {
- // No try block necessary - Do not throw
- FW_CPlatformPoint plfmPt = point;
- #ifdef FW_BUILD_MAC
- return ::PtInRgn(plfmPt, rgn);
- #endif
- #ifdef FW_BUILD_WIN
- return ::PtInRegion(rgn, plfmPt.X(), plfmPt.Y());
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_RectInRegion
- //----------------------------------------------------------------------------------------
-
- FW_Boolean SL_API FW_RectInRegion(ODRgnHandle rgn, const FW_SRect& rect)
- {
- // No try block necessary - Do not throw
- FW_CPlatformRect plfmRect = rect;
- #ifdef FW_BUILD_MAC
- return ::RectInRgn(&plfmRect, rgn);
- #endif
- #ifdef FW_BUILD_WIN
- return ::RectInRegion(rgn, &plfmRect);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_IsEmptyRegion
- //----------------------------------------------------------------------------------------
-
- FW_Boolean SL_API FW_IsEmptyRegion(ODRgnHandle rgn)
- {
- // No try block necessary - Do not throw
- #ifdef FW_BUILD_MAC
- return ::EmptyRgn(rgn);
- #endif
- #ifdef FW_BUILD_WIN
- return ::CombineRgn(rgn, rgn, rgn, RGN_AND) == NULLREGION;
- #endif
- }
-
- #ifdef FW_BUILD_MAC
- //----------------------------------------------------------------------------------------
- // PrivMacOpenRegion
- //----------------------------------------------------------------------------------------
-
- static GrafPtr PrivMacOpenRegion()
- {
- GrafPtr svPort;
- ::GetPort(&svPort);
- ::SetPort(FW_gScratchPort);
- ::OpenRgn();
- return svPort;
- }
- #endif
-
- #ifdef FW_BUILD_MAC
- //----------------------------------------------------------------------------------------
- // PrivMacCloseRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle PrivMacCloseRegion(GrafPtr svPort)
- {
- ODRgnHandle hRgn = ::FW_NewRegion();
- ::CloseRgn(hRgn);
- OSErr err = ::QDError();
- if(err != noErr)
- {
- ::FW_DisposeRegion(hRgn);
- hRgn = NULL;
- }
- ::SetPort(svPort);
- return hRgn;
- }
- #endif
-
- #ifdef FW_BUILD_WIN
-
- //----------------------------------------------------------------------------------------
- // PrivWinInsetRegionPoint
- //----------------------------------------------------------------------------------------
-
- static void PrivWinInsetRegionRectangle(LPPOINT lppt, int dx, int dy, const POINT& ptCenter)
- {
- if (lppt->x < ptCenter.x)
- {
- if ((lppt->x += dx) > ptCenter.x)
- lppt->x = ptCenter.x;
- }
- else
- {
- if ((lppt->x -= dx) < ptCenter.x)
- lppt->x = ptCenter.x;
- }
-
- if (lppt->y < ptCenter.y)
- {
- if((lppt->y += dy) > ptCenter.y)
- lppt->y = ptCenter.y;
- }
- else
- {
- if ((lppt->y -= dy) < ptCenter.y)
- lppt->y = ptCenter.y;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // PrivWinInsetRegionRectangle
- //----------------------------------------------------------------------------------------
-
- static void PrivWinInsetRegionRectangle(LPRECT lpRect, int dx, int dy, const POINT& ptCenter)
- {
- PrivWinInsetRegionRectangle(((LPPOINT) lpRect) + 0, dx, dy, ptCenter);
- PrivWinInsetRegionRectangle(((LPPOINT) lpRect) + 1, dx, dy, ptCenter);
- }
-
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_WriteRegion
- //----------------------------------------------------------------------------------------
-
- void SL_API FW_WriteRegion(ODRgnHandle rgnHandle, FW_HWritableStream hStream, FW_PlatformError* error)
- {
- FW_ERR_TRY
- {
- FW_CWritableStream stream(hStream);
-
- #ifdef FW_BUILD_WIN
- long size = ::GetRegionData(rgnHandle, 0, NULL);
-
- FW_CAcquireTemporaryMemory tempMem(size);
- LPRGNDATA rgnData = (LPRGNDATA) tempMem.GetPointer();
- ::GetRegionData(rgnHandle, size, rgnData);
-
- stream << size;
- stream.Write(rgnData, size);
- #endif
- #ifdef FW_BUILD_MAC
- short size = (*rgnHandle)->rgnSize;
-
- FW_CAcquireLockedSystemHandle memHandle((FW_PlatformHandle)rgnHandle);
- void* rgnData = memHandle.GetPointer();
-
- stream << size;
- stream.Write(rgnData, size);
- #endif
- }
- FW_ERR_CATCH
- }
-
- //----------------------------------------------------------------------------------------
- // FW_ReadRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle SL_API FW_ReadRegion(FW_HReadableStream hStream, FW_PlatformError* error)
- {
- FW_ERR_TRY
- {
- FW_CReadableStream stream(hStream);
-
- #ifdef FW_BUILD_WIN
- long size;
- stream >> size;
-
- FW_CAcquireTemporaryMemory tempMem(size);
- LPRGNDATA rgnData = (LPRGNDATA) tempMem.GetPointer();
- stream.Read(rgnData, size);
-
- return ::ExtCreateRegion(NULL, size, rgnData);
- #endif
- #ifdef FW_BUILD_MAC
- short size;
- stream >> size;
-
- FW_CAcquireTemporarySystemHandle memHandle(size);
- void* rgnData = memHandle.GetPointer();
-
- stream.Read(rgnData, size);
-
- memHandle.Orphan();
- return (ODRgnHandle) memHandle.GetPlatformHandle();
- #endif
- }
- FW_ERR_CATCH
- return NULL;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_UnionRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle SL_API FW_UnionRegion(ODRgnHandle rgn1, ODRgnHandle rgn2)
- {
- // No try block necessary - Do not throw
- ODRgnHandle dstRgn = ::FW_NewRegion();
- if (dstRgn == NULL)
- return NULL;
-
- #ifdef FW_BUILD_MAC
- ::UnionRgn(rgn1, rgn2, dstRgn);
- #endif
- #ifdef FW_BUILD_WIN
- ::CombineRgn(dstRgn, rgn1, rgn2, RGN_OR);
- #endif
-
- return dstRgn;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_XorRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle SL_API FW_XorRegion(ODRgnHandle rgn1, ODRgnHandle rgn2)
- {
- // No try block necessary - Do not throw
- ODRgnHandle dstRgn = ::FW_NewRegion();
- if (dstRgn == NULL)
- return NULL;
-
- #ifdef FW_BUILD_MAC
- ::XorRgn(rgn1, rgn2, dstRgn);
- #endif
- #ifdef FW_BUILD_WIN
- ::CombineRgn(dstRgn, rgn1, rgn2, RGN_XOR);
- #endif
-
- return dstRgn;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_SubtractRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle SL_API FW_SubtractRegion(ODRgnHandle rgn1, ODRgnHandle rgn2)
- {
- // No try block necessary - Do not throw
- ODRgnHandle dstRgn = ::FW_NewRegion();
- if (dstRgn == NULL)
- return NULL;
-
- #ifdef FW_BUILD_MAC
- ::DiffRgn(rgn1, rgn2, dstRgn);
- #endif
- #ifdef FW_BUILD_WIN
- ::CombineRgn(dstRgn, rgn1, rgn2, RGN_DIFF);
- #endif
-
- return dstRgn;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_IntersectRegion
- //----------------------------------------------------------------------------------------
-
- ODRgnHandle SL_API FW_IntersectRegion(ODRgnHandle rgn1, ODRgnHandle rgn2)
- {
- // No try block necessary - Do not throw
- ODRgnHandle dstRgn = ::FW_NewRegion();
- if (dstRgn == NULL)
- return NULL;
-
- #ifdef FW_BUILD_MAC
- ::SectRgn(rgn1, rgn2, dstRgn);
- #endif
- #ifdef FW_BUILD_WIN
- ::CombineRgn(dstRgn, rgn1, rgn2, RGN_AND);
- #endif
-
- return dstRgn;
- }
-
-